/*
* Copyright (C) 2015 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.errai;
import java.lang.instrument.Instrumentation;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
/**
* A Java Agent that ensures all attempts at loading a class whose package and
* name match a particular pattern end up loading a trivial subclass of
* java.lang.Object.
* <p>
* The motivation for creating this agent was to hide GWT client-local classes
* from app servers: attempts to load these classes run into several kinds of
* dependency resolution problems: client-side GWT API that does not exist on
* the server, as well as missing native methods for JSNI.
*/
public class ClientLocalClassHidingAgent {
private static final String DEFAULT_CLASS_NAME_PATTERN = ".*/client/local/.*";
/**
* Populates a map with default options, overriding and supplementing them
* with those specified in the options string.
*
* @param options
* @return
*/
private static final Map<String, String> parseOptionsWithDefaults(String options) {
Map<String, String> map = new HashMap<String, String>();
if (options == null) options = "";
// load map with defaults
map.put("debugAgent", Boolean.FALSE.toString());
map.put("classPattern", DEFAULT_CLASS_NAME_PATTERN);
for (String keyval : options.split(",")) {
String key;
String val;
int equalsIdx = keyval.indexOf("=");
if (equalsIdx >= 0) {
key = keyval.substring(0, equalsIdx);
val = keyval.substring(equalsIdx + 1);
} else {
key = keyval;
val = null;
}
map.put(key, val);
}
return map;
}
public static void premain(String agentArgs, Instrumentation inst) {
Map<String, String> options = parseOptionsWithDefaults(agentArgs);
boolean debug = Boolean.parseBoolean(options.get("debugAgent"));
Pattern hideClassesPattern = Pattern.compile(options.get("classPattern"));
inst.addTransformer(new ClientLocalClassHider(hideClassesPattern, debug));
inst.addTransformer(new GwtLinkerClassHider(debug));
}
}